package com.iuie.ns.devtools.transfer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.springframework.stereotype.Component;

import com.iuie.ns.devtools.element.BaseDevElement;
import com.iuie.ns.devtools.element.DevElement;
import com.iuie.ns.devtools.element.JavaMapperClassDevElement;
import com.iuie.ns.devtools.to.DevBodyTO;
import com.iuie.ns.devtools.to.DevHeaderTO;
import com.iuie.ns.devtools.to.ResultMapDevHeaderTO;
import com.iuie.ns.frame.utils.ListUtils;
import com.iuie.ns.frame.utils.StringUtils;

@Component("javaMapperTransfer")
public class JavaMapperDevTransfer extends BaseDevTransfer {

	@Override
	public String transfer(List<? extends DevBodyTO> list, DevHeaderTO header) {
		ResultMapDevHeaderTO mHeader = (ResultMapDevHeaderTO) header;
		
		final List<DevElement> allElements = new ArrayList<>();
		if (isAllow(mHeader.getAddOne())) {
			DevElement comment = this.getComment("新增单条记录", Arrays.asList(new String[]{"item"}));
			DevElement params = new BaseDevElement("@Param(\"item\") " + mHeader.getClassName() + " item");
			DevElement element = new BaseDevElement("\tvoid addOne(", params, ");\n\n");
			
			allElements.add(comment);
			allElements.add(element);
		}
		
		List<DevBodyTO> primaryKeys = this.getPrimaryKeys(list);
		if (isAllow(mHeader.getFindById())) {
			DevElement comment = this.getCommentByBodys("根据ID查询单条记录", primaryKeys);
			List<DevElement> params = this.getParams(primaryKeys);
			DevElement element = new BaseDevElement("\t" + mHeader.getClassName() + " findById(", params, ");\n\n");
			
			allElements.add(comment);
			allElements.add(element);
		}
		
		if (isAllow(mHeader.getDeleteById())) {
			DevElement comment = this.getCommentByBodys("根据ID删除单条记录", primaryKeys);
			List<DevElement> params = this.getParams(primaryKeys);
			DevElement element = new BaseDevElement("\tInteger deleteById(", params, ");\n\n");
			
			allElements.add(comment);
			allElements.add(element);
		}
		
		if (isAllow(mHeader.getUpdateOne())) {
			DevElement comment = this.getComment("更新单条记录", Arrays.asList(new String[]{"item"}));
			DevElement params = new BaseDevElement("@Param(\"item\") " + mHeader.getClassName() + " item");
			DevElement element = new BaseDevElement("\tvoid updateOne(", params, ");\n\n");
			
			allElements.add(comment);
			allElements.add(element);
		}
		
		if (isAllow(mHeader.getFindByCondition())) {
			DevElement comment = this.getComment("根据条件查询", Arrays.asList(new String[]{"item"}));
			DevElement params = new BaseDevElement("@Param(\"item\") " + mHeader.getClassName() + " item");
			DevElement element = new BaseDevElement("\tList<" + mHeader.getClassName() + "> findByCondition(", params, ");\n\n");
			
			allElements.add(comment);
			allElements.add(element);
		}
		
		if (isAllow(mHeader.getBatchAdd())) {
			DevElement comment = this.getComment("批量新增", Arrays.asList(new String[]{"records"}));
			DevElement params = new BaseDevElement("@Param(\"records\") List<" + mHeader.getClassName() + "> records");
			DevElement element = new BaseDevElement("\tvoid batchAdd(", params, ");\n\n");
			
			allElements.add(comment);
			allElements.add(element);
		}
		if (isAllow(mHeader.getBatchUpdate())) {
			DevElement comment = this.getComment("批量更新", Arrays.asList(new String[]{"records"}));
			DevElement params = new BaseDevElement("@Param(\"records\") List<" + mHeader.getClassName() + "> records");
			DevElement element = new BaseDevElement("\tvoid batchUpdate(", params, ");\n\n");
			
			allElements.add(comment);
			allElements.add(element);
		}
		if (isAllow(mHeader.getBatchDelete())) {
			DevElement comment = this.getComment("批量删除", Arrays.asList(new String[]{"records"}));
			DevElement params = new BaseDevElement("@Param(\"records\") List<" + mHeader.getClassName() + "> records");
			DevElement element = new BaseDevElement("\tvoid batchDelete(", params, ");\n\n");
			
			allElements.add(comment);
			allElements.add(element);
		}
		
		return new JavaMapperClassDevElement(mHeader) {
			
			@Override
			protected List<DevElement> getChildren() {
				return allElements;
			}
		}.build();
	}

	private boolean isAllow(String type) {
		return StringUtils.equals(type, "1");
	}
	
	private List<DevElement> getParams(List<DevBodyTO> params) {
		if (ListUtils.isNotEmpty(params)) {
			List<DevElement> list = new ArrayList<>();
			Iterator<DevBodyTO> it = params.iterator();
			while (it.hasNext()) {
				DevBodyTO body = it.next();
				StringBuilder sb = new StringBuilder(12);
				sb.append("@Param(\"")
					.append(body.getAttributeName())
					.append("\") ")
					.append(getFieldTypeRelationMap().get(body.getFieldType()))
					.append(" ")
					.append(body.getAttributeName());
				if (it.hasNext()) {
					sb.append(", ");
				}
				list.add(new BaseDevElement(sb.toString()));
			}
			return list;
		}
		return null;
	}
	
	private DevElement getCommentByBodys(String description, List<DevBodyTO> params) {
		if (ListUtils.isNotEmpty(params)) {
			List<String> list = new ArrayList<>();
			Iterator<DevBodyTO> it = params.iterator();
			while (it.hasNext()) {
				DevBodyTO body = it.next();
				list.add(body.getAttributeName());
			}
			return this.getComment(description, list);
		}
		return null;
	}
	
	private DevElement getComment(String description, List<String> params) {
		List<DevElement> list = new ArrayList<>();
		list.add(new BaseDevElement("\t/**\n\t * ", description));
		if (params != null) {
			for (int i = 0; i < params.size(); i ++ ) {
				list.add(new BaseDevElement("\n\t * @param ", params.get(i)));
			}
		}
		list.add(new BaseDevElement("\n\t */\n"));
		return new BaseDevElement(list);
	}
	
	private List<DevBodyTO> getPrimaryKeys(List<? extends DevBodyTO> list) {
		if (ListUtils.isNotEmpty(list)) {
			List<DevBodyTO> primaryKeys = new ArrayList<>();
			Iterator<? extends DevBodyTO> it = list.iterator();
			while (it.hasNext()) {
				DevBodyTO body = it.next();
				if (body.isIdAttribute()) {
					primaryKeys.add(body);
				}
			}
			return primaryKeys;
		}
		return null;
	}
}
